/**
 * @description: axios 请求方式封装
 * @fileName: options.js
 * @author: Evan
 * @date: 2021-08-17 11:44:09
 * @version: V1.0.0
 */
import Service from './axios'
import Emiter from './emiter'
import type { ApiConfig } from './type'

const request = function (config: ApiConfig) {
  Emiter.emit('api:start', config)
  return Service(config)
    .then(resp => {
      Emiter.emit('api:end', config, resp)
      if (config.original) {
        let response = resp.data || {}
        if (response.code == 200) {
        } else if (response.code == 401) {
          Emiter.emit('api:un_auth', config, response)
        } else {
          Emiter.emit('api:invalid', config, response)
        }
        return resp
      }
      let response = resp.data || {}
      if (resp.status == 200) {
        if (response.code != void 0) {
          if (response.code == 200) {
            return response.data
          } else if (response.code == 401) {
            Emiter.emit('api:un_auth', config, response)
          } else {
            Emiter.emit('api:invalid', config, response)
            return Promise.reject(response)
          }
        }
        return response
      } else {
        return Promise.reject(response)
      }
    })
    .catch(er => {
      Emiter.emit('api:end', config, er)
      Emiter.emit('api:error', config, er)
      return Promise.reject(er)
    })
}

/**
 * get 请求
 * @param { String | ApiConfig } url 请求链接
 * @param { Object } params 请求参数
 * @param { Boolean | string | HTMLElement } loading 加载弹窗 为dom元素则挂在到dom，字符串则为 dom 选择器
 * @param { Boolean } silent 是否静默 默认值 false （会自动在页面抛出错误信息）
 * @param { Boolean } original 是否返回接口原始数据 默认值 false
 * @returns { Promise } 接口返回数据
 */
request.get = function (
  url: string | ApiConfig,
  params = {},
  loading: boolean | string | HTMLElement = true,
  silent = false,
  original = false
) {
  if (typeof url === 'string') {
    const config: ApiConfig = { url, method: 'get', params, silent, loading, original }
    return this(config)
  }
  url.method = 'get'
  return this(url)
}

/**
 * post 请求
 * @param { String | ApiConfig } url 请求链接
 * @param { Object } data 请求参数
 * @param { Boolean | string | HTMLElement } loading 加载弹窗 为dom元素则挂在到dom，字符串则为 dom 选择器
 * @param { Boolean } silent 是否静默 默认值 false （会自动在页面抛出错误信息）
 * @param { Boolean } original 是否返回接口原始数据 默认值 false
 * @returns { Promise } 接口返回数据
 */
request.post = function (
  url: string | ApiConfig,
  data = {},
  loading: boolean | string | HTMLElement = true,
  silent = false,
  original = false
) {
  if (typeof url === 'string') {
    const config: ApiConfig = { url, method: 'post', data, silent, loading, original }
    return this(config)
  }
  url.method = 'post'
  return this(url)
}

/**
 * post 请求
 * @param { String } url 请求链接
 * @param { Object } data 请求参数
 * @param { Boolean | string | HTMLElement } loading 加载弹窗 为dom元素则挂在到dom，字符串则为 dom 选择器
 * @param { Boolean } silent 是否静默 默认值 false （会自动在页面抛出错误信息）
 * @param { Boolean } original 是否返回接口原始数据 默认值 false
 * @returns { Promise } 接口返回数据
 */
request.postFormData = function (
  url: string,
  data = {},
  loading: boolean | string | HTMLElement = true,
  silent = false,
  original = false
) {
  let config: ApiConfig & {
    headers: {
      [key: string]: string
    }
  } = {
    url,
    method: 'post',
    data,
    silent,
    loading,
    original,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  }
  return this(config)
}

/**
 * put 请求
 * @param { String | ApiConfig } url 请求链接
 * @param { Object } data 请求参数
 * @param { Boolean | string | HTMLElement } loading 加载弹窗 为dom元素则挂在到dom，字符串则为 dom 选择器
 * @param { Boolean } silent 是否静默 默认值 false （会自动在页面抛出错误信息）
 * @param { Boolean } original 是否返回接口原始数据 默认值 false
 * @returns { Promise } 接口返回数据
 */
request.put = function (
  url: string | ApiConfig,
  data = {},
  loading: boolean | string | HTMLElement = true,
  silent = false,
  original = false
) {
  if (typeof url === 'string') {
    const config: ApiConfig = { url, method: 'put', data, silent, loading, original }
    return this(config)
  }
  url.method = 'put'
  return this(url)
}

/**
 * delete 请求
 * @param { String | ApiConfig } url 请求链接
 * @param { Object } params 请求参数
 * @param { Boolean | string | HTMLElement } loading 加载弹窗 为dom元素则挂在到dom，字符串则为 dom 选择器
 * @param { Boolean } silent 是否静默 默认值 false （会自动在页面抛出错误信息）
 * @param { Boolean } original 是否返回接口原始数据 默认值 false
 * @returns { Promise } 接口返回数据
 */
request.delete = function (
  url: string | ApiConfig,
  params = {},
  loading: boolean | string | HTMLElement = true,
  silent = false,
  original = false
) {
  if (typeof url === 'string') {
    const config: ApiConfig = { url, method: 'delete', params, silent, loading, original }
    return this(config)
  }
  url.method = 'delete'
  return this(url)
}

export default request
